/*!
 * jquery.event.drop.live - v 2.2
 * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
 * Open Source MIT License - http://threedubmedia.com/code/license
 */
// Created: 2010-06-07
// Updated: 2012-05-21
// REQUIRES: jquery 1.7.x, event.drag 2.2, event.drop 2.2

;(function($){ // secure $ jQuery alias

// local refs (increase compression)
var $event = $.event,
// ref the drop special event config
drop = $event.special.drop,
// old drop event add method
origadd = drop.add,
// old drop event teradown method
origteardown = drop.teardown;

// allow events to bubble for delegation
drop.noBubble = false;

// the namespace for internal live events
drop.livekey = "livedrop";

// new drop event add method
drop.add = function( obj ){
  // call the old method
  origadd.apply( this, arguments );
  // read the data
  var data = $.data( this, drop.datakey );
  // bind the live "dropinit" delegator
  if ( !data.live && obj.selector ){
    data.live = true;
    $event.add( this, "dropinit."+ drop.livekey, drop.delegate );
  }
};

// new drop event teardown method
drop.teardown = function(){
  // call the old method
  origteardown.apply( this, arguments );
  // read the data
  var data = $.data( this, drop.datakey ) || {};
  // remove the live "dropinit" delegator
  if ( data.live ){
    // remove the "live" delegation
    $event.remove( this, "dropinit", drop.delegate );
    data.live = false;
  }
};

// identify potential delegate elements
drop.delegate = function( event, dd ){
  // local refs
  var elems = [], $targets,
  // element event structure
  events = $.data( this, "events" ) || {};
  // query live events
  $.each( events || [], function( key, arr ){
    // no event type matches
    if ( key.indexOf("drop") !== 0 )
      return;
    $.each( arr, function( i, obj ){
      // locate the elements to delegate
      $targets = $( event.currentTarget ).find( obj.selector );
      // no element found
      if ( !$targets.length )
        return;
      // take each target...
      $targets.each(function(){
        // add an event handler
        $event.add( this, obj.origType +'.'+ drop.livekey, obj.origHandler || obj.handler, obj.data );
        // remember new elements
        if ( $.inArray( this, elems ) < 0 )
          elems.push( this );
      });
    });
  });
  // may not exist when artifically triggering dropinit event
  if ( dd )
    // clean-up after the interaction ends
    $event.add( dd.drag, "dragend."+drop.livekey, function(){
      $.each( elems.concat( this ), function(){
        $event.remove( this, '.'+ drop.livekey );
      });
    });
  //drop.delegates.push( elems );
  return elems.length ? $( elems ) : false;
};

})( jQuery ); // confine scope